﻿//===============================================================================
//	PlayerLoginQueueManager.h
//	用户登录排队管理器
//===============================================================================

#pragma once

#include <list>

#include "ConstantDefine.h"

// 排队状态
enum
{
	LoginQueueInfo_Status_None  = 0,		// 不在登录队列内
	LoginQueueInfo_Status_Wait  = 1,		// 在等待队列内
	LoginQueueInfo_Status_Login = 3,		// 在可以登录集合内
	LoginQueueInfo_Status_LoginCheck = 4,	// 在可以登录集合内， 并且前端已经检测了这个状态
	LoginQueueInfo_Status_LoginBegin = 5,	// 在可以登录集合内， 并且已经开始登录
};

// 排队信息
struct LoginQueueInfo
{
	uint32_t	m_accountId;	// 玩家
	uint32_t	m_socketId;		// 链接Id
	uint32_t	m_status;		// 排队状态
	uint32_t	m_xxx;
	uint64_t	m_time;			// 准备登录时间

};

// 返回给客户端的排队信息
struct LoginQueueWaitInfo
{
	uint32_t	m_status;		// 排队状态
	uint32_t	m_pos;			// 排队序号
	uint32_t	m_wait;			// 需要等待的时间(ms)
};

//-------------------------------------------------------------------------------
class PlayerLoginQueueManager
{
private:
	uint64_t m_lastTimeoutCheck;
	uint32_t m_max_login_accounts_num;	// 最大并行数量
	uint32_t m_check_timeout_millsec;	// 超时等待时间(ms)
	std::list<LoginQueueInfo> m_wait_accounts;		// 排队的玩家
	std::list<LoginQueueInfo> m_login_accounts;		// 可以登录/正在登录的玩家

	// TODO : 使用list的查询效率较低， 目前暂不优化

public:
	PlayerLoginQueueManager();
	~PlayerLoginQueueManager();
	void Initialize(uint32_t maxNum, uint32_t millsec);

	void checkLoginAccounts();								// 检查从等待移到可登录
	void romveLoginAccount(uint32_t accountId);

	uint32_t checkWaitAccount(uint32_t accountId, uint32_t socketId, bool bInsert);	// 查询排队
	void accountloginBegin(uint32_t accountId);		// 玩家开始登录
	void accountloginFinished(uint32_t accountId);		// 玩家登录完成

	LoginQueueWaitInfo getLoginQueueInfo(uint32_t accountId, uint32_t socketId);

	void checkTimeout();						// 超时检查
	void disconnect(uint32_t socketId);		// 断开链接事件
	bool check_connect(uint32_t socketId);		// 断开链接检查

	uint64_t getNowMillsec();

};


